package io.github.kimmking.kkconfig.repository;

import cn.kimmking.utils.HttpUtils;
import com.alibaba.fastjson.TypeReference;
import io.github.kimmking.kkconfig.spring.ConfigMeta;
import lombok.Getter;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * Description for this class.
 *
 * @Author : kimmking(kimmking@apache.org)
 * @create 2024/4/19 21:07
 */
public class KKRepositoryImpl implements KKRepository {
    ConfigMeta meta;
    List<KKRepositoryChangeListener<Map<String, String>>> listeners = new ArrayList<>();
    ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);

    public KKRepositoryImpl(ConfigMeta meta) {
        this.meta = meta;
        executor.scheduleAtFixedRate(this::heartbeat, 1_000, 5_000, TimeUnit.MILLISECONDS);
    }

    @Override
    public Map<String, String> getConfig() {
        if (LAST_CONFIG.isEmpty()) {
            fetchAll();
        }
        return LAST_CONFIG;
    }

    @Override
    public void addChangeListener(KKRepositoryChangeListener<Map<String, String>> listener) {
        listeners.add(listener);
    }

    private void fetchAll() {
        String url = meta.toListUrl();
        List<Configs> configs = HttpUtils.httpGet(url, new TypeReference<List<Configs>>() {
        });
        System.out.println(" ======= configs ======");
        System.out.println(configs);
        System.out.println(" ======= configs ======");
        Map<String, String> config = new HashMap<>();
        configs.forEach(c -> {
            config.put(c.getPkey(), c.getPval());
        });
//
//            Map<String, String> config = new HashMap<>();
//            config.put("kk.a", "a100");
//            config.put("kk.b", "b101");
//            config.put("kk.c", "c102");
        listeners.forEach(listener -> {
            listener.onRepositoryChange(new KKRepositoryChangeListener
                    .KKRepositoryChangeEvent<>(meta, config));
        });
        LAST_CONFIG.clear();
        LAST_CONFIG.putAll(config);
    }

    private void heartbeat() {
        try {
            String url = meta.toHeartUrl();
            long current = Long.parseLong(HttpUtils.get(url));
            Long last = LAST_TIMESTAMP.getOrDefault(meta.buildKey(), 0L);
            System.out.println(" ======>>>> heartbeat current = " + current + ", last = " + last);
            if (current > last) {
                System.out.println(" ====>>>> need update for new timestamp ...");
                LAST_TIMESTAMP.put(meta.buildKey(), current);
                fetchAll();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
